package com.lnlyj.alert;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class Alert implements ActionView.ActionCallback {

    public static final String TAG = "Alert";

    private FrameLayout rootView;
    private TextView titleTv;
    private TextView messageTv;
    private LListView listView;
    private SelectAdapter adapter;
    private LinearLayout optionLayout;
    private LinearLayout actionLayout;

    private WeakReference<Activity> wr;

    private Handler handler = new Handler(Looper.getMainLooper());
    private Builder builder;

    public interface OnItemSelectedListener {
        void onSingleItemClick(LObject obj);

        void onMultiItemSelected(List<LObject> selected);
    }

    private Alert(Activity context, Builder builder) {
        this.wr = new WeakReference<>(context);
        this.builder = builder;
        init();
    }

    private void init() {
        if (getActivity() != null) {

            rootView = (FrameLayout) View.inflate(getActivity(), R.layout.layout_alert, null);

            titleTv = rootView.findViewById(R.id.tv_title);
            messageTv = rootView.findViewById(R.id.tv_message);
            listView = rootView.findViewById(R.id.list_view);
            optionLayout = rootView.findViewById(R.id.layout_option);
            actionLayout = rootView.findViewById(R.id.layout_action);

            rootView.setSoundEffectsEnabled(builder.cancel);
            rootView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (builder.cancel) {
                        dismiss();
                    }
                }
            });

            rootView.requestFocus();
            rootView.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    Log.d(TAG, "rootView onKey: ");
                    if (event.getAction() == KeyEvent.ACTION_DOWN) {
                        if (builder.cancel) {
                            dismiss();
                        }
                        return true;
                    }

                    return false;
                }
            });

            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) rootView.getChildAt(0).getLayoutParams();

            if (builder.style == Style.ALERT) {
                lp.gravity = Gravity.CENTER;
            } else if (builder.style == Style.ACTION_SHEET) {
                lp.gravity = Gravity.BOTTOM;
                lp.bottomMargin = Utils.getNavigationBarHeight(getActivity()) + 10;
            }

            rootView.getChildAt(0).setLayoutParams(lp);

            titleTv.setText(builder.title);

            if (TextUtils.isEmpty(builder.title)) {
                ((ViewGroup) titleTv.getParent()).setVisibility(View.GONE);
            } else {
                ((ViewGroup) titleTv.getParent()).setVisibility(View.VISIBLE);
                titleTv.setText(builder.title);
            }

            if (TextUtils.isEmpty(builder.message)) {
                messageTv.setVisibility(View.GONE);
            } else {
                messageTv.setVisibility(View.VISIBLE);
                messageTv.setText(builder.message);
            }

            if (builder.adapter == null) {
                listView.setVisibility(View.GONE);
            } else {
                listView.setVisibility(View.VISIBLE);
                listView.setAdapter(builder.adapter);

                listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        builder.adapter.setSelect(builder.adapter.getItem(position));

                        if (builder.itemSelectedListener != null) {

                            if (builder.isMultiSelected) {
                                builder.itemSelectedListener.onMultiItemSelected(builder.adapter.getMultiList());
                            } else {
                                builder.itemSelectedListener.onSingleItemClick(builder.adapter.getSingleSelect());
                            }
                        }

                    }
                });
            }

            int i = 0;
            for (ActionView view : builder.actions) {
                View child = view.getView();
                view.setInnerCallback(this);
                actionLayout.addView(child);
                if (i != builder.actions.size() - 1) {
                    actionLayout.addView(View.inflate(getActivity(), R.layout.layout_line, null));
                }
            }

        }
    }

    private Activity getActivity() {
        return wr.get();
    }

    private void requestFocus() {
        rootView.setFocusable(true);
        rootView.setFocusableInTouchMode(true);
        rootView.requestFocus();
    }

    public void show() {
        if (getActivity() != null) {
            if (!isShow()) {
                ViewGroup group = (ViewGroup) getActivity().getWindow().getDecorView();
                group.addView(rootView);
                requestFocus();
            }
        }
    }

    public void show(int delayMillis) {
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                dismiss();
            }
        }, delayMillis);
    }

    public void dismiss() {
        if (isShow()) {
            ViewGroup group = (ViewGroup) rootView.getParent();
            group.removeView(rootView);
        }
    }

    public boolean isShow() {
        if (rootView.getParent() == null) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public void onAction(View v) {
        dismiss();
    }

    public static class Style {
        public static final int ALERT = 1;
        public static final int ACTION_SHEET = 2;
    }

    public static class SelectAdapter extends BaseAdapter {

        private List<LObject> list;
        private boolean isMultiSelect;
        private List<LObject> multiList = new ArrayList<>();
        private LObject singleSelect;

        public SelectAdapter(List<LObject> list, boolean multi) {
            this.list = list;
            this.isMultiSelect = multi;
        }

        @Override
        public int getCount() {
            return list == null ? 0 : list.size();
        }

        @Override
        public LObject getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {

            if (convertView == null) {
                convertView = View.inflate(parent.getContext(), R.layout.item_select, null);
            }

            TextView text = convertView.findViewById(R.id.text);
            ImageView check = convertView.findViewById(R.id.iv_check);

            text.setText(getItem(position).getText());

            if (isMultiSelect) {
                check.setVisibility(multiList.contains(getItem(position)) ? View.VISIBLE : View.GONE);
            } else {
                check.setVisibility(getItem(position) == singleSelect ? View.VISIBLE : View.GONE);
            }

            return convertView;
        }

        public void setSelect(LObject obj) {
            if (isMultiSelect) {
                if (multiList.contains(obj)) {
                    multiList.remove(obj);
                } else {
                    multiList.add(obj);
                }
            } else {
                if (!obj.equals(singleSelect)) {
                    singleSelect = obj;
                }
            }
            notifyDataSetChanged();
        }

        public LObject getSingleSelect() {
            return singleSelect;
        }

        public List<LObject> getMultiList() {
            return multiList;
        }
    }

    public static class Builder {
        private Activity context;
        private int style = Style.ALERT;
        private String title;
        private String message;
        private boolean cancel = true;
        private SelectAdapter adapter;
        private boolean isMultiSelected;
        private OnItemSelectedListener itemSelectedListener;
        private List<ActionView> actions = new ArrayList<>();


        public Builder(Activity context) {
            this.context = context;
        }

        public Builder withStyle(int style) {
            this.style = style;
            return this;
        }

        public Builder withTitle(int resId) {
            withTitle(context.getString(resId));
            return this;
        }

        public Builder withTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder withMessage(int resId) {
            withMessage(context.getString(resId));
            return this;
        }

        public Builder withMessage(String message) {
            this.message = message;
            return this;
        }

        public Builder withCancelable(boolean cancel) {
            this.cancel = cancel;
            return this;
        }

        public Builder withArray(List<LObject> list, boolean multiSelected, OnItemSelectedListener listener) {
            this.adapter = new SelectAdapter(list, multiSelected);
            this.isMultiSelected = multiSelected;
            this.itemSelectedListener = listener;
            return this;
        }

        public Builder withAction(int resId, ActionView.ActionCallback callback) {
            withAction(context.getString(resId), callback);
            return this;
        }

        public Builder withAction(String action, ActionView.ActionCallback callback) {
            actions.add(new ActionView(context, action, callback));
            return this;
        }

        public Alert create() {
            return new Alert(context, this);
        }

        public void show() {
            create().show();
        }
    }

    public Bitmap blur(Bitmap bmp) {
        Bitmap result = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_4444);

        RenderScript rs = RenderScript.create(getActivity());
        Allocation in = Allocation.createFromBitmap(rs, bmp);
        Allocation out = Allocation.createFromBitmap(rs, result);

        ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

        blur.setRadius(25);
        blur.setInput(in);
        blur.forEach(out);
        out.copyTo(result);
        rs.destroy();
        return result;
    }

    public static Bitmap getBitmapFromView(View v) {
        Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565);
        Canvas c = new Canvas(b);
        v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
        // Draw background
        Drawable bgDrawable = v.getBackground();
        if (bgDrawable != null)
            bgDrawable.draw(c);
        else
            c.drawColor(Color.WHITE);
        // Draw view to canvas
        v.draw(c);
        return b;
    }
}
